<?php
/**
 * Service Base of the buddy
 *
 * @author xinqiyang
 *
 */
class BaseService extends Base
{

	/**
	 * Service Base Add function
	 * this is add to db point // to add to db
	 * @param string $object
	 * @param array $data
	 */
	public static function add($object,$data)
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			$r = $mysql->add($data);
			//logDebug($mysql->getLastSql());
			if($r && $object <> 'userinfo'){ //if userinfo is the same key of account
				$sql = "INSERT INTO sz_object (id,object) VALUES({$data['id']},'{$object}')";
				$result = $mysql->execute($sql);
				if(!$result) {
					logFatal('object insert error:'.$sql);
				}
			}
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}

	/**
	 * adds dataset to db
	 * @param string $object
	 * @param array $array dataset
	 */
	public static function adds($object,$array)
	{
		$r = false;
		//if is dataset then add all
		if(count($array) && isset($array[0]) && is_array($array[0])){
			foreach ($array as $val)
			{
				$r = self::add($object, $val);
			}
			return $r;
		}
		return self::add($object, $array);
	}

	/**
	 * Save method
	 *
	 * @param string $object
	 * @param array $array
	 */
	public static function save($object,$array,$where='')
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			$r = empty($where) ? $mysql->save($array) : $mysql->where($where)->save($array);
			logDebug($mysql->getLastSql());
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}
	/**
	 * save then clean cache
	 * @param string $object
	 * @param array $array
	 * @param string $where
	 */
	public static function saveClean($object,$array,$where='')
	{
		$r = self::save($object, $array,$where);
		if($r){
				$key = 'h:'.$array['id'];
				self::redisDeleteKeys(array($key));
				return true;
		}
		return false;
	}

	/**
	 * get object from db
	 * @param string $object
	 * @param bigint $id
	 * @param string $fields
	 * @param string $where
	 */
	public static function get($object,$id,$fields='',$where='')
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			if($id)
			{
				$r = empty($fields) ? $mysql->find($id) : $mysql->field($fields)->find($id);
			}elseif($where){
				$r = empty($fields) ? $mysql->where($where)->find() : $mysql->where($where)->field($fields)->find();
			}
			//@todo need remove var_dump
			logDebug($mysql->getLastSql());
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}

	/**
	 * get objects from db
	 * @param string $object
	 * @param array $data 
	 * @param string $fields
	 */
	public static function gets($object,$array,$fields='*')
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			$r = $mysql->field($fields)->where($array)->select();
			//@todo need remove var_dump
			logDebug($mysql->getLastSql());
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}
	
	/**
	 * do query from the db
	 * @param string $object
	 * @param string $sql SQL
	 */
	public static function query($object,$sql)
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			$r = $mysql->query($sql);
			//@todo need remove var_dump
			logDebug($mysql->getLastSql());
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}
	
	public static function queryRow($object,$where,$fields='*')
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			$r = $mysql->field($fields)->where($where)->find();
			//@todo need remove var_dump
			logDebug($mysql->getLastSql());
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}
	
	public static function queryField($object,$where,$field)
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			$r = $mysql->getField($field,$where);
			//@todo need remove var_dump
			logDebug($mysql->getLastSql());
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}

	/**
	 * get objects from db
	 * @param string $object
	 * @param array $data
	 * @param string $fields
	 */
	public static function getsKeyID($object,$array,$fields='*')
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			$select['keyid'] = true;
			$r = $mysql->field($fields)->where($array)->select($select);
			//@todo need remove var_dump
			logDebug($mysql->getLastSql());
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}

	/**
	 * get objects from db
	 * @param string $object
	 * @param array $data
	 * @param string $fields
	 */
	public static function getsByPage($object,$where,$offset,$pageSize=20,$fields='*')
	{
		$r = false;
		try{
			$mysql = MMysql::instance($object);
			$select['keyid'] = true;
			$select['page'] = "$offset,$pageSize";
			$select['field'] = $fields;
			$select['where'] = $where;
			$r = $mysql->select($select);
			//@todo need remove var_dump
			logDebug($mysql->getLastSql());
		}catch (MException $e) {
			logFatal($e->__toString());
		}
		return $r;
	}

	/**
	 * hash instance Incr By field
	 * if u will dcr then set $count = -1
	 * @param unknown_type $key
	 * @param unknown_type $field
	 * @param unknown_type $count
	 * @param unknown_type $node
	 */
	public static function redisHCount($key,$field,$count=1,$node='redis')
	{
		$r = MRedis::instance($node);
		return $r->hIncrBy($key,$field,$count);
	}

	/**
	 * get list data
	 * @param string $key
	 * @param int $from
	 * @param int $pageSize
	 * @param string $node
	 */
	public static function redisListData($key,$from,$type='h:',$pageSize=20,$node='redis',$mysqlnode='mysql')
	{
		$idList = self::redisGetList($key, $from,$pageSize,$node);
		if(!empty($idList)){
			return self::redisGetHashes($idList,$type,$node,$mysqlnode);
		}
		return false;
	}

	/**
	 * get sys hot
	 * $array field  key from,number ,if number equal 0 means all
	 */
	public static function redisGetList($key,$from,$pageSize=20,$node='redis')
	{
		$r = MRedis::instance($node);
		$from = ($from < 1 ) ? 0 : $from-1;
		$pageSize = $from + $pageSize - 1;
		return $r->lRange($key,$from,$pageSize);
		
	}

	/**
	 * get more hashes
	 * @param string $prefix
	 * @param array $idList  id array
	 * @param array $keys  key array
	 * @param string $node redis server node
	 */
	public static function redisGetHashes($idList,$prefix='h:',$sortKey='id',$node='redis',$mysqlnode='mysql')
	{
		$arr = array();
		if(!is_array($idList) && !empty($idList))
		{
			$idList = array($idList);
		}
		if(is_array($idList) && !empty($idList)){
			$r = MRedis::instance($node);
			if(is_array($idList) && count($idList))
			{
				foreach ($idList as $val)
				{
					
					$m = $r->hGetAll($prefix.$val);
					if($m)
					{
						isset($m[$sortKey]) ? $arr["$m[$sortKey]"] = $m : $arr[$val] = $m;
					}else{
						$row = self::getHashBuild($val,$prefix,$mysqlnode,$node);
						if($row)
						{
							isset($row[$sortKey]) ? $arr["$row[$sortKey]"] = $row : $arr[$val] = $row;
						}
					}
				}
				if(count($arr) == 1){
					return current($arr);
				}
				return $arr;
			}
		}
		return false;
	}

	public static function getHashBuild($id,$prefix='',$mysqlnode='mysql',$redisnode='redis')
	{
		$row = false;
		$object = self::get('object', $id);
		if(!empty($object['object']))
		{
			//return the get
			$r = MRedis::instance($redisnode);
			$key = $prefix.$object['object'];
			//var_dump($key);die;
			//rebuild data type
			switch ($key)
			{
				//table name 
				case "h:product":
				case "h:brand":
				case "h:url":
				case "h:topic":
				case "h:post":
				case "h:group":
				case "h:account":
				case "h:mail":
				case "h:image":
					$row = self::get($object['object'], $id);
					break;
				case "h:lastsay:account":
					$where = "user_id=$id AND status=0 ORDER BY ID DESC";
					$row = self::queryRow('post', $where);
					break;
				case "h:userinfo:account":
					$row = self::get('userinfo', $id);
					break;
			}
			
			
			if(!empty($row)){
				$bolset =  $r->hmSet($prefix.$id,$row);
				if(!$bolset)
				{
					logWARNING(__CLASS__.'/'.__FUNCTION__." set redis hash data error id:$val");
				}
			}
			return $row;
		}

		
		return false;
	}

	/**
	 * Set the keys to The List key
	 * @param string $key
	 * @param array $array
	 */
	public static function redisSetList($key,$array,$listLength=500,$node='redis')
	{
		$rbol = true;
		$r = MRedis::instance($node);
		if(is_array($array))
		{
			$array = array_slice($array, 0,500);
			//TODO:need to 
			$r->delete($key);
			foreach ($array as $val){
				$rbol = $r->rPush($key,$val);
				if(!$rbol)
				{
					logWARNING(__CLASS__.'/'.__FUNCTION__."lPush ERROR :$key,$value");
				}
			}
		}
		return $rbol;
	}


	public static function addToEventQueue($array,$method='')
	{
		$queue = Queue::instance();
		$array['method'] = $method;
		$qr = $queue->put('event', Json::encode($array));
		return ;
	}

	/**
	 * delete object by array id or id
	 * @param $array mixed string/array
	 */
	public static function destory($object,$array)
	{
		if(count($array) && isset($array[0]) && is_array($array[0])){
			return self::save($object, array('status'=>1),'id in '.strin($array));
		}
		return self::save($object, array('status'=>1),'id='.$array);
	}

	/**
	 * delete key/value from redis
	 * @param mixed $keys if is string and include * ,then get keys then delete it, else if is array then delete keys
	 * @param unknown_type $node
	 */
	public static function redisDeleteKeys($keys,$node='redis')
	{
		$redis = MRedis::instance($node);
		if(!is_array($keys))
		{
			if(is_int(strpos($keys, '*')))
			{
				$keys = $redis->keys($keys);
			}
		}
		return $redis->delete($keys);
	}

}